
/************************************************************************/
/* Core                                                                 */
/************************************************************************/
#include "Core/Manager.h"

/************************************************************************/
/* Game                                                                 */
/************************************************************************/
#include "Game/Game Objects/Marios/BaseMario.h"
#include "Game/Game Objects/Towers/BaseTower.h"

/************************************************************************/
/* Resources                                                            */
/************************************************************************/
#include "Resources/Resource.h"

/************************************************************************/
/* PROJECT                                                              */
/************************************************************************/


namespace TD_Game {
	
	template <typename T>
	unsigned int Manager<T>::m_currObjId = 0;

	/************************************************************************/
	/* Functionalities                                                      */
	/************************************************************************/
	template <typename T>
	void Manager<T>::createObject(T * g_pObj) {
		std::stringstream convertedInt;
		convertedInt << m_currObjId;
		createObject(convertedInt.str(), g_pObj);
	}

	template <typename T>
	void Manager<T>::createObject(const string &g_objStr, T * g_pObj) {
		m_objStringMap[g_objStr] = g_pObj;
		m_objMap[m_currObjId++] = g_pObj;
	}

	template <typename T>
	void Manager<T>::createObject(unsigned int g_objID, T * g_pObj) {
		std::stringstream convertedInt;
		convertedInt << g_objID;
		m_objStringMap[convertedInt.str()] = g_pObj;
		m_objMap[g_objID] = g_pObj;
	}

	/************************************************************************/
	/* ctors and dtors                                                      */
	/************************************************************************/
	template <typename T>
	Manager<T>::Manager() {

	}

	template <typename T>
	Manager<T>::Manager(const Manager &rhs) {
		m_objMap = rhs.getObjectMap();
	}

	template <typename T>
	Manager<T> & Manager<T>::operator =(const Manager &rhs) {
		m_objMap = rhs.getObjectMap();
		return(*this);
	}
	
	/**
	Access
	*/
	template <typename T>
	inline T* Manager<T>::getObject(unsigned int objId) const {
		T * pObject = NULL;
		typename map<unsigned int, T *>::const_iterator iter = m_objMap.find(objId);
		if (iter == m_objMap.end()) return NULL;
		pObject = iter->second;
		return(pObject);
	}
	
	template <typename T>
	T* Manager<T>::getObject(const string objName) const {
		T * pObject = NULL;
		typename map<string, T *>::const_iterator iter = m_objStringMap.find(objName);
		if (iter == m_objStringMap.end()) return NULL;
		pObject = iter->second;
		return(pObject);
	}
		
	template <typename T>
	const map<unsigned int, T*> & Manager<T>::getObjectMap() const {
		return(m_objMap);
	}
	
	template <typename T>
	void Manager<T>::deleteObject(unsigned int objId) {
		T * pObject = NULL;
		/** Typename map used for gcc compiler problems with templates.*/
		typename map<unsigned int, T *>::iterator iter = m_objMap.find(objId);
		if (iter == m_objMap.end()) {
			return;
		}
	
		std::stringstream convertedInt;
		convertedInt << objId;
		/** Typename map used for gcc compiler problems with templates.*/
		typename map<string, T *>::iterator strIter = m_objStringMap.find(convertedInt.str());
			
		if (strIter == m_objStringMap.end()) {
			return;
		}
			
		pObject = iter->second;
		delete pObject;
		m_objStringMap.erase(strIter);
		m_objMap.erase(iter);
			
	}
	
	/** Declaration of which subset of templates that are going to be used.*/
	template class Manager<BaseMario>;
	template class Manager<BaseTower>;
	template class Manager<Resource>;
}